#    Copyright 2012 New Mexico EPSCoR
#
#    This file is part of Teacher's P.E.T.
#
#    Teacher's P.E.T. is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Teacher's P.E.T. is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Teacher's P.E.T..  If not, see <http://www.gnu.org/licenses/>.

from django.shortcuts import render_to_response, RequestContext, Http404, HttpResponseRedirect, get_object_or_404
from django.contrib import messages
from filetransfers.api import serve_file

from apps.course.models import Course
from apps.participants.models import CourseParticipant
from models import Activity, Subactivity, ActivityViewed, ActivityResponseFileUpload
from functions import CreateActivityResponseFormset
from context_processors import make_activity_menu, make_activity_menu_html
from apps.course.functions import course_reverse

import logging
import datetime

logger = logging.getLogger('pet.apps.activities.views')

# Create your views here.

def view(request, course=None, category=None, title=None, collection_category=None, collection_title=None):
    logger.fxn_entry("course=%s,category=%s,title=%s,collection_category=%s,collection_title=%s",course,category,title,collection_category,collection_title)
    #Get the course we are in
    TheCourse = Course.find_or_404(course)

    #Get the activity and activitycollection
    if not category and not title:
        #index here?
        raise Http404
    TheActivity = None
    TheActivityCollection = None
    if category and title: TheActivity = Activity.find(TheCourse.course_id,category_slug=category,title_slug=title)
    if collection_category and collection_title: TheActivityCollection = Activity.find(TheCourse.course_id,category_slug=collection_category,title_slug=collection_title)
    if not TheActivityCollection and TheActivity and Subactivity.objects.filter(parent_activity=TheActivity):
        TheActivityCollection = TheActivity

    #Get the user and the courseparticipant and the associated questionforms
    TheUser = request.user
    TheCourseParticipant = CourseParticipant.find(course=TheCourse.course_id,user=TheUser)
    context_dict = {}
    if (TheActivity and not TheActivity.is_public):
        if not TheUser.is_superuser and not TheCourseParticipant:
            logger.info("Anonymous user trying to access non-public activity '%s'",TheActivity)
            messages.info(request,"Access to this part of the site requires course authentication");
            return HttpResponseRedirect(course_reverse('course_index',TheCourse))

    if TheActivity and request.method == "POST":
        Error = False
        context_dict.update(CreateActivityResponseFormset(course=TheCourse,activity=TheActivity,user=TheUser,postinfo=request.POST,files=request.FILES))
        #Go through the returned items and save the responses
        FormCompleted = True
        for question in context_dict['Questions']:
            form = question.form
            if question.form.is_valid():
                if question.form.cleaned_data['response']: FormCompleted = FormCompleted and True
                else: FormCompleted = False
                if question.form.has_changed():
                    question.form.save()
                else: logger.form_unchanged("question %s unchanged" % (question.question_number))
            else: FormCompleted = False; Error = True; logger.debug("question %s invalid %s" % (question.question_number, question.form))
        if FormCompleted:
            ActivityViewInfo = ActivityViewed.objects.filter(user=TheUser, activity=TheActivity)[0]
            if not ActivityViewInfo.completed: ActivityViewInfo.completed = datetime.datetime.now(); ActivityViewInfo.save()
        if not Error:
            context_dict.update(CreateActivityResponseFormset(course=TheCourse,activity=TheActivity,user=TheUser))

    else:
        context_dict.update(CreateActivityResponseFormset(course=TheCourse,activity=TheActivity,user=TheUser))
        #Update the fact that this user has viewed this activity (it auto-increments views)
        # we check CourseParticipant instead of User because we don't care if admins view the activity
        if TheCourseParticipant:
            ActivityView = ActivityViewed.objects.filter(user=TheUser,activity=TheActivity)
            if not ActivityView: ActivityView = ActivityViewed(user=TheUser,activity=TheActivity)
            else: ActivityView = ActivityView[0]
            ActivityView.save()

    #Create our context_dict with questions and items
    ActivityCollectionDict = {}
    if TheActivityCollection: TheActivityCollection.display_title = TheActivityCollection.title
    else: TheActivity.display_title = TheActivity.title
    make_activity_menu(TheCourse,ActivityCollectionDict,[TheActivityCollection] if TheActivityCollection else [TheActivity])
    context_dict.update({'ActivityCollection':TheActivityCollection if TheActivityCollection else None,'ActivityCollectionMenu':make_activity_menu_html(ActivityCollectionDict),'Activity':TheActivity})
    logger.fxn_exit("Showing Activity %s in ActivityCollection %s",TheActivity,TheActivityCollection)
    return render_to_response('activities/view.html',context_dict,context_instance=RequestContext(request))

def view_question(request, course=None, category=None, title=None, collection_category=None, collection_title=None, id=None):
	logger.debug("course=%s,category=%s,title=%s,collection_category=%s,collection_title=%s,id=%s",course,category,title,collection_category,collection_title,id)
	#Get the course we are in
	TheCourse = Course.find_or_404(course)

	#Get the activity and activitycollection
	if not category or not title or not id:
		logger.debug("Missing one of category (%s), title (%s), or id (%s)",category, title, id)
		raise Http404
	TheActivity = None
	if category and title: TheActivity = Activity.find(TheCourse.course_id,category_slug=category,title_slug=title)

	#Get the user and the courseparticipant and the associated questionforms
	TheUser = request.user
	TheCourseParticipant = None
	context_dict = {'id':id, 'Activity':TheActivity}
	if TheActivity and not TheActivity.is_public:
		TheCourseParticipant = CourseParticipant.find(TheCourse.course_id,TheUser)
	if TheActivity: context_dict.update(CreateActivityResponseFormset(course=TheCourse,activity=TheActivity,course_participant=TheCourseParticipant,id=id))

	kwargs = {'category':category,'title':title}
	if collection_category and collection_title:
		kwargs['collection_category'] = collection_category
		kwargs['collection_title'] = collection_title
	context_dict['ActivityLink'] = course_reverse('apps.activities.views.view',course,**kwargs)

	return render_to_response('activities/view_question.html',context_dict,context_instance=RequestContext(request))

def download(request, course=None, category=None, title=None, collection_category=None, collection_title=None, id=None, pk=None):
	logger.debug("course=%s,pk=%s,category=%s,title=%s,collection_category=%s,collection_title=%s,id=%s",course,pk,category,title,collection_category,collection_title,id)
	#Get the course we are in
	TheCourse = Course.find_or_404(course)
	
	#Check the response exists
	Response = get_object_or_404(ActivityResponseFileUpload,pk=pk)
	
	#Make sure that the owner of the response or the instructor is requesting the file
	TheUser = request.user
	TheCourseParticipant = CourseParticipant.find_or_404(course=TheCourse.course_id,user=TheUser)
	if Response.user != TheUser and TheCourseParticipant.status != "INSTRUCTOR" and TheCourseParticipant.status != "ASSISTANT":
		logger.info("User %s trying to access file (%s) belonging to %s",TheUser, Response.response, Response.user)
		raise Http404
	
	return serve_file(request,Response.response)
	